/*
 * CloudBank Mobile Knowledge Sharing for Language Learners
 * Supported by the JISC Rapid Innovation Programme #jiscri
 *
 * Copyright (C) 2010 University of Brighton
 *
 * Licensed under the GNU General Public License v3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.gnu.org/licenses/gpl.html
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package uk.ac.brighton.itrg.cloudbank;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.util.Random;

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.telephony.TelephonyManager;

public class CB
{
	// control local logging
	public static final boolean DEBUG_LOCAL = true;
	
	// control remote logging (send exceptions to server)
	public static final boolean DEBUG_REMOTE = false;
	
	
    // Emulator documentation: 10.0.2.2 = 127.0.0.1 on your development machine
	private static final String LOCALHOST = "http://10.0.2.2/itrg.brighton.ac.uk/cloudbank/";	
	private static final String HOST = "http://itrg.brighton.ac.uk/cloudbank/";

	
	// constants for CloudBank REST API requests
	public static final String API_VERSION 	= "1.1";
	public static final String API_KEY 		= "00000000000000000000000000000000";
	public static final String API_SECRET 	= "00000000000000000000000000000000";
	public static final String API_FORMAT 	= "xml";
	public static       String API_UID 		= "unknown"; // initialised on application start-up!
	
	
	// tag settings for this user, initialised on application start-up in ActivityMain
	public static       String INCLUDE_TAGS = null;
	public static       String EXCLUDE_TAGS = null;
	public static       String DEFAULT_TAGS = null;
	
	
	// constants for WebView controls
	public static final String MIMETYPE = "text/html";
	public static final String ENCODING = "UTF-8";	

	
	// time in ms after which cached data is re-queried
	public static final long CACHE_MAX_AGE= 3 * 60 * 1000; 	
	
	
    // get CloudBank host 
	public static final String getHost()
	{
		if(isEmulator()) return LOCALHOST;
		else             return HOST;
	}
	
    // get CloudBank REST server 
	public static final String getRestServer()
	{
		return getHost() + "api/" + API_VERSION + "/rest.php";
	}
	
    // get default search engine 
	public static final String getSearchEngine()
	{
		if(isEmulator()) return LOCALHOST; // just to reach something valid
		else             return "http://www.google.com/m/search";
	}
	
	
    // get CloudBank Help page for an Activity 
	public static final String getHelpPage(Activity a)
	{
		return getHost() + "app/help/index.php?topic=" + a.getClass().getName();
	}

	
	// are we running on the emulator? cache this value!
	private static Boolean flagEmulator = null;
	public static final boolean isEmulator()
	{
		if(flagEmulator == null) 
		{
			flagEmulator = new Boolean(Build.PRODUCT.equals("sdk"));
		}
		return flagEmulator.booleanValue();
	}
	
	
	// create a random string  
    private static final String CHARSET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXYZ";
    public static String getRandom(int length) 
    {
        Random rand = new Random(System.currentTimeMillis());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) 
        {
            int pos = rand.nextInt(CHARSET.length());
            sb.append(CHARSET.charAt(pos));
        }
        return sb.toString();
    }
    
	
	// create a MD5 hex string
	public static String md5(String s) 
	{
		try
		{
	        // Create MD5 Hash
	        MessageDigest md5 = MessageDigest.getInstance("MD5");
	        md5.update(s.getBytes());
	        byte digest[] = md5.digest();
	        
	        // Create Hex String
	        StringBuffer sb = new StringBuffer();
	        for (int i=0; i<digest.length; i++)
	        {
	        	String hex = Integer.toHexString(0xFF & digest[i]);
	        	if(hex.length()<2) sb.append(0);
	            sb.append(hex);
	        }

	        return sb.toString();
		}
		catch(Exception e) 
		{
			Logger.log(e);
		}

		return "";
	}

	
	// copy a file (I cannot believe this is still not in the API!)
	public static void fileCopy(File source, File target)
	{
		InputStream is = null;
        OutputStream os = null;

        try
        {
			is = new FileInputStream(source);
	        os = new FileOutputStream(target);
			streamCopy (is, os);
			is.close();
			os.close();
        }
        catch(Exception e)
        {
        	if(is!=null) try {is.close();} catch(Exception ex){}
        	if(os!=null) try {os.close();} catch(Exception ex){}
        	Logger.log(e);
        }
	}
	
	
	// just transport the bytes...
	public static void streamCopy(InputStream is, OutputStream os) throws Exception
	{
		byte[] buf = new byte[1024];
		int i = 0;
		while ((i = is.read(buf)) != -1) 
		{
		    os.write(buf, 0, i);
		}			
	}
	
	
	// The T-Mobile Pulse is not standard Android and requires some work-arounds. 
	public static boolean isTMobilePulse()
	{
		return (Build.MODEL.equalsIgnoreCase("pulse") && Build.USER.equalsIgnoreCase("huawei"));
	}
	
	
	// Print general phone information
	public static void dumpPhoneInfo(Context c)
	{
		if(! DEBUG_LOCAL) return;
		
        Logger.log("Build properties:");  					// ---phone---					---emulator---
        Logger.log("Build.BOARD", Build.BOARD); 			// sapphire						unknown
        Logger.log("Build.BRAND", Build.BRAND); 			// vodafone						generic
        Logger.log("Build.DEVICE", Build.DEVICE); 			// sapphire						generic
        Logger.log("Build.DISPLAY", Build.DISPLAY);			// CRC1							sdk-eng 1.5 CUPCAKE ...
        Logger.log("Build.FINGERPRINT", Build.FINGERPRINT);	// vodafone/vfpoineer/...		generic/sdk/generic/:1.5/CUPCAKE...
        Logger.log("Build.HOST", Build.HOST);		 		// undroid16.mtv.corp...		apa27.mtv.corp.google.com
        Logger.log("Build.ID", Build.ID);		 			// CRC1							CUPCAKE
        Logger.log("Build.MODEL", Build.MODEL); 			// HTC Magic					sdk
        Logger.log("Build.PRODUCT", Build.PRODUCT); 		// vfpoineer					sdk
        Logger.log("Build.TAGS", Build.TAGS); 				// ota-rel-keys, test-keys		test-keys
        Logger.log("Build.TIME", Build.TIME); 		 		// 1246...						1246....
        Logger.log("Build.TYPE", Build.TYPE);		 		// user							eng
        Logger.log("Build.USER", Build.USER);				// android-build				android-build
        
        TelephonyManager tm = (TelephonyManager) c.getSystemService(Context.TELEPHONY_SERVICE);
        
        int callState = tm.getCallState();
	    String callStateString = "NA";
	    switch (callState) 
	    {
	      case TelephonyManager.CALL_STATE_IDLE:    callStateString = "IDLE"; break;
	      case TelephonyManager.CALL_STATE_OFFHOOK: callStateString = "OFFHOOK"; break;
	      case TelephonyManager.CALL_STATE_RINGING: callStateString = "RINGING"; break;
	    }
        Logger.log("CallState", callStateString);
        Logger.log("DeviceId", tm.getDeviceId());
        Logger.log("DeviceSoftwareVersion", tm.getDeviceSoftwareVersion());
        Logger.log("Line1Number", tm.getLine1Number());
        Logger.log("NetworkCountryIso", tm.getNetworkCountryIso());
        Logger.log("NetworkOperator", tm.getNetworkOperator());
        Logger.log("NetworkOperatorName", tm.getNetworkOperatorName());

        int phoneType = tm.getPhoneType();
	    String phoneTypeString = "NA";
	    switch (phoneType) 
	    {
	      case TelephonyManager.PHONE_TYPE_GSM:  phoneTypeString = "GSM"; break;
	      case TelephonyManager.PHONE_TYPE_NONE: phoneTypeString = "NONE"; break;
	    }
        Logger.log("PhoneType", phoneTypeString);
        Logger.log("SimCountryIso", tm.getSimCountryIso());
        Logger.log("SimOperator", tm.getSimOperator());
        Logger.log("SimOperatorName", tm.getSimOperatorName());
        Logger.log("SimSerialNumber", tm.getSimSerialNumber());
        Logger.log("SubscriberId", tm.getSubscriberId());

        int simState = tm.getSimState();
	    String simStateString = "NA";
	    switch (simState) 
	    {
	      case TelephonyManager.SIM_STATE_ABSENT:         simStateString = "ABSENT";    break;
	      case TelephonyManager.SIM_STATE_NETWORK_LOCKED: simStateString = "NETWORK_LOCKED"; break;
	      case TelephonyManager.SIM_STATE_PIN_REQUIRED:   simStateString = "PIN_REQUIRED";   break;
	      case TelephonyManager.SIM_STATE_PUK_REQUIRED:   simStateString = "PUK_REQUIRED";   break;
	      case TelephonyManager.SIM_STATE_READY:          simStateString = "STATE_READY";    break;
	      case TelephonyManager.SIM_STATE_UNKNOWN:        simStateString = "STATE_UNKNOWN";  break;
	    }
        Logger.log("SimState", simStateString);
	}

}
